﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Communergy.Common;
using Communergy.Data;
using Communergy.Common.Events;

namespace Communergy.Enio
{
    public class EnioExportCommand : IDataExportCommand
    {
		#region Fields (4) 

        TimeSpan ageOfRecords;
        string enioApiKey;
        DateTime exportTime = DateTime.Now;
        string meterId;

		#endregion Fields 

		#region Constructors (1) 

        public EnioExportCommand(string meterId, TimeSpan ageOfRecords, string enioApiKey)
        {
            this.meterId = meterId;
            this.ageOfRecords = ageOfRecords;
            this.enioApiKey = enioApiKey;
        }

		#endregion Constructors 

		#region Properties (2) 

        public TimeSpan ExportInterval { get; set; }

        public IRepositoryFactory LocalCacheRepository { get; set; }

		#endregion Properties 

		#region Delegates and Events (1) 

		// Events (1) 

        public event DataExportHandler DataExportEvent;

		#endregion Delegates and Events 

		#region Methods (5) 

		// Public Methods (1) 

        public void ExportData()
        {
            List<RealtimeEnergyReading> realtimeRecords = GetNewRecords();
            if (realtimeRecords != null && realtimeRecords.Count > 0)
            {
                MeterApi.Service service = new MeterApi.Service(enioApiKey);
                var sources = service.GetAllSources();

                var sourceId = sources.First().SourceId;

                foreach (var realtimeRecord in realtimeRecords)
                {
                    try
                    {
                        var ticks = exportTime.Subtract(realtimeRecord.ReadingDateTime).Ticks;
                        var uploadSource = new MeterApi.Source
                        {
                            SourceId = sourceId,
                            TimeSinceReading = ticks,
                            Watts = realtimeRecord.Watts
                        };
                        service.UpdateSource(uploadSource);
                    }
                    catch (Exception e)
                    {
                        HandleError(e);
                    }
                }
                string updateData = string.Format("Enio: Exported {0} records from between {1} and {2}, average {3} Watts", realtimeRecords.Count, realtimeRecords.First().ReadingDateTime.ToString(), realtimeRecords.Last().ReadingDateTime.ToString(), realtimeRecords.Average(r => r.Watts));
                UpdateStatus(updateData);
            }
        }
		// Private Methods (4) 

        private List<RealtimeEnergyReading> GetNewRecords()
        {
            DataAccessLayer dataAccess = new DataAccessLayer(LocalCacheRepository);
            DateTime dateFrom = DateTime.Now.Subtract(ageOfRecords);
            var records = dataAccess.Get_ElectricityRealtime(meterId, dateFrom, DateTime.Now);
            return records;
        }

        private void HandleError(Exception e)
        {
            UpdateStatus(e.Message);
        }

        private void RaiseNewDataExportEvent(DataExporterEventArgs de)
        {
            if (DataExportEvent != null)
            {
                DataExportEvent(this, de);
            }
        }

        private void UpdateStatus(string message)
        {
            DataExporterEventArgs de = new DataExporterEventArgs();
            de.Message = message;
            RaiseNewDataExportEvent(de);
        }

		#endregion Methods 
    }
}
